package cardwall.client.view;

import cardwall.shared.Task;
import com.allen_sauer.gwt.dnd.client.*;
import com.allen_sauer.gwt.dnd.client.drop.BoundaryDropController;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.*;

import java.util.List;
import java.util.Iterator;
import java.util.ArrayList;

/**
 * @author $LastChangedBy: vogensen $
 * @version $Revision: 2 $
 */
public class WallPanel extends AbsolutePanel {

    private PickupDragController widgetDragController;
    private List<CardUpdateListener> cardUpdateListenerList = new ArrayList<CardUpdateListener>();
    private List<CardSelectedListener> cardSelectedListenerList = new ArrayList<CardSelectedListener>();

    public void init() {
        // use the boundary taskPanel as this composite's widget
        setSize("100%", "100%");
        Grid grid = new Grid(7, 5);

        // initialize our widget drag controller
        PickupDragController widgetDragController = new PickupDragController(this, false);
//        widgetDragController.setBehaviorDragStartSensitivity(5);
        widgetDragController.setBehaviorMultipleSelection(false);
        DragHandler dragHandler = new DragHandlerAdapter() {
            int left;
            int top;

            public void onDragStart(DragStartEvent event) {
                CardPanel cardPanel = (CardPanel)event.getContext().draggable;
                left = cardPanel.getAbsoluteLeft();
                top = cardPanel.getAbsoluteTop();
            }

            public void onPreviewDragEnd(DragEndEvent event) throws VetoDragException {
                CardPanel cardPanel = (CardPanel)event.getContext().draggable;
//                System.out.println("pde "+cardPanel.getAbsoluteLeft()+" "+cardPanel.getAbsoluteTop());
            }

            public void onPreviewDragStart(DragStartEvent event) throws VetoDragException {
                CardPanel cardPanel = (CardPanel)event.getContext().draggable;
//                System.out.println("pds "+cardPanel.getAbsoluteLeft()+" "+cardPanel.getAbsoluteTop());
            }

            public void onDragEnd(DragEndEvent event) {
                System.out.println(""+left+" "+top);
                CardPanel cardPanel = (CardPanel)event.getContext().draggable;
//                System.out.println(""+cardPanel.getAbsoluteLeft()+" "+cardPanel.getAbsoluteTop());
                if(!(left == cardPanel.getAbsoluteLeft()-2 && top == cardPanel.getAbsoluteTop()-2)) { // dont know where the +2 pixels come frome???
                    for (CardUpdateListener cardUpdateListener : cardUpdateListenerList) {
                        cardUpdateListener.onUpdate(cardPanel);
                    }
                }
                for (CardSelectedListener cardSelectedListener : cardSelectedListenerList) {
                    cardSelectedListener.onSelection(cardPanel);
                }
            }
        };
        this.widgetDragController = widgetDragController;
        this.widgetDragController.addDragHandler(dragHandler);

        // initialize a widget drop controller
        BoundaryDropController widgetDropController = new BoundaryDropController(this, true);
        widgetDragController.registerDropController(widgetDropController);

        add(grid);
        grid.setSize("100%", "100%");
        int numRows = grid.getRowCount();
        int numColumns = grid.getColumnCount();
        grid.getCellFormatter().setHeight(0,0, "30px");
        grid.getCellFormatter().setWidth(0,0, "75px");
        grid.setWidget(0, 1, new Label("Planned"));
        grid.setWidget(0, 2, new Label("In progress"));
        grid.setWidget(0, 3, new Label("Review"));
        grid.setWidget(0, 4, new Label("Done"));

        for (int row = 0; row < numRows; row++) {
            if(row > 0) {
                grid.setWidget(row, 0, new Label("Story " + row));
            }
            for (int col = 0; col < numColumns; col++) {
                DOM.setStyleAttribute(grid.getCellFormatter().getElement(row, col), "border", "1px solid black");
            }
        }
    }

    public void addCardUpdateListener(CardUpdateListener cardUpdateListener) {
        cardUpdateListenerList.add(cardUpdateListener);
    }

    public void addCardSelectedListener(CardSelectedListener cardSelectedListener) {
        cardSelectedListenerList.add(cardSelectedListener);
    }

    public void refreshTasks(List<Task> taskList) {
        Task selectedTask = null;
        
        // remove old
        Iterator<Widget> iterator = iterator();
        while (iterator.hasNext()) {
            Widget widget = iterator.next();
            if (widget instanceof CardPanel) {
                CardPanel cardPanel = (CardPanel) widget;
                if(cardPanel.getSelected()) {
                    selectedTask = cardPanel.getTask();
                }
                iterator.remove();
            }
        }

        // add new
        for (Task task : taskList) {
            CardPanel cardPanel = new CardPanel(task);
            if(selectedTask != null && task.getId() == selectedTask.getId()) {
                cardPanel.setSelected(true);
            }
            // make the widget draggable
            widgetDragController.makeDraggable(cardPanel);
            int top = (int) (getOffsetHeight()/1000.0*task.getTop());
            int left = (int) (getOffsetWidth()/1000.0*task.getLeft());
            add(cardPanel, left, top);
        }

//        Iterator<Widget> iterator = iterator();
//        while (iterator.hasNext()) {
//            Widget widget = iterator.next();
//            if (widget instanceof CardPanel) {
//                CardPanel cardPanel = (CardPanel) widget;
//                Task task1 = cardPanel.getTask();
//                boolean found = false;
//                for (Task task2 : taskList) {
//                    if(task1.getId() == task2.getId()) {
//                        found = true;
//                        // if found and equal - do nothing
//                        // if found and not equal - update
//                        if(!task1.equals(task2)) {
//                            iterator.remove();
//                            CardPanel cp = addCardPanel(task2);
//                            if(cardPanel.getSelected()) {
//                                cp.setSelected(true);
//                            }
//                        }
//                        break;
//                    }
//                }
//                // if not found - remove
//                if(!found) {
//                    iterator.remove();
//                }
//            }
//        }
//
//        // if new - add
//        for (Task task2 : taskList) {
//            iterator = iterator();
//            boolean found = false;
//            while (iterator.hasNext()) {
//                Widget widget = iterator.next();
//                if (widget instanceof CardPanel) {
//                    CardPanel cardPanel = (CardPanel) widget;
//                    if (cardPanel.getTask().equals(task2)) {
//                        found = true;
//                        break;
//                    }
//                }
//            }
//            if (!found) {
//                addCardPanel(task2);
//            }
//        }
    }

    private CardPanel addCardPanel(Task task) {
        CardPanel cardPanel = new CardPanel(task);
        // make the widget draggable
        widgetDragController.makeDraggable(cardPanel);
        int top = (int) (getOffsetHeight() / 1000.0 * task.getTop());
        int left = (int) (getOffsetWidth() / 1000.0 * task.getLeft());
        add(cardPanel, left, top);
        return cardPanel;
    }

    public void repositionTasks() {
        Iterator<Widget> iterator = iterator();
        while (iterator.hasNext()) {
            Widget widget = iterator.next();
            if (widget instanceof CardPanel) {
                Task task = ((CardPanel)widget).getTask();
                int top = (int) (getOffsetHeight()/1000.0*task.getTop());
                int left = (int) (getOffsetWidth()/1000.0*task.getLeft());
                DOM.setStyleAttribute(widget.getElement(), "top", (new StringBuilder()).append(top).append("px").toString());
                DOM.setStyleAttribute(widget.getElement(), "left", (new StringBuilder()).append(left).append("px").toString());
            }
        }
    }

    public void setSelected(Task task) {
        Iterator<Widget> iterator = iterator();
        while (iterator.hasNext()) {
            Widget widget = iterator.next();
            if (widget instanceof CardPanel) {
                CardPanel cardPanel = (CardPanel) widget;
                cardPanel.setSelected(cardPanel.getTask().equals(task));
            }
        }
    }
}